﻿namespace Jsl.FxCop
{
    using System;
    using System.Linq;
    using Microsoft.FxCop.Sdk;

    /// <summary>
    /// A utility class that helps test source code.
    /// </summary>
    /// <remarks>
    /// Debug and release build are significantly different. Rules should be tested compiled in both ways.
    /// </remarks>
    public class CodeTestHelper
    {
        private readonly CompileHelper compileHelper;
        private string classNameToTest = "Class";
        private string methodNameToTest = "Method";

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="CodeTestHelper"/> class.
        /// </summary>
        /// <param name="compileHelper">The compile helper.</param>
        public CodeTestHelper(CompileHelper compileHelper)
        {
            this.compileHelper = compileHelper;
        }
        #endregion Constructors

        #region Public Properties
        /// <summary>
        /// Gets or sets the name of the class to test.
        /// </summary>
        /// <value>The name of the class to test.</value>
        public string ClassNameToTest
        {
            get { return this.classNameToTest; }

            set { this.classNameToTest = value; }
        }

        /// <summary>
        /// Gets or sets the name of the method to test.
        /// </summary>
        /// <value>The name of the method to test.</value>
        public string MethodNameToTest
        {
            get { return this.methodNameToTest; }

            set { this.methodNameToTest = value; }
        }
        #endregion Public Properties

        #region Public Methods
        public void Test(Action<bool, Method> action)
        {
            this.Test(true, method => action(true, method));
            this.Test(false, method => action(false, method));
        }

        public void Test(bool debugMode, Action<Method> action)
        {
            var assembly = this.compileHelper.Generate(debugMode);

            var classToTest = assembly.GetTypeNode(this.ClassNameToTest);
            var methodToTest = classToTest.GetMethod(this.MethodNameToTest);

            action(methodToTest);
        }
        #endregion Public Methods
    }
}